package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.BaseException;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.mapper.UserMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.socket.WebSocketServer;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderWithDetailVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AddressBookMapper addressBookMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WebSocketServer webSocketServer;

    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        //为了确保订单有效首先得判断地址是否为空以及购物车是否为空
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new BaseException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if (shoppingCartList == null || shoppingCartList.size() == 0) {
            throw new BaseException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //清空购物车
        shoppingCartMapper.deleteAll(shoppingCart);
        //先设置订单的信息
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        BeanUtils.copyProperties(addressBook, orders);
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setAddress(addressBook.getDetail());
        orderMapper.insert(orders);

        //再添加订单的子信息
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(orders.getId());
            orderDetailList.add(orderDetail);
        }
        //为订单设置用户名
        User user = userMapper.getByid(userId);
        orders.setUserName(user.getName());

        orderMapper.insertBatch(orderDetailList);

        return new OrderSubmitVO().builder()
                .id(orders.getId())
                .orderTime(orders.getOrderTime())
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .build();
    }

    @Override
    public void payment(OrdersPaymentDTO ordersPaymentDTO) {
        Orders order = new Orders();
        order.setNumber(ordersPaymentDTO.getOrderNumber());
        List<Orders> ordersList = orderMapper.list(order);
        if (ordersList != null && ordersList.size() == 1) {
            order = ordersList.get(0);
            if (order.getPayStatus() == Orders.PAID) {
                throw new BaseException("订单已支付");
            }
        }else {
            throw new BaseException("订单不存在");
        }

    }

    @Override
    public void paySuccess(String orderNumber) {
        Orders order = Orders.builder()
                .number(orderNumber)
                .build();
        List<Orders> ordersList = orderMapper.list(order);
        if (ordersList != null && !ordersList.isEmpty()) {
            order = ordersList.get(0);
            order.setCheckoutTime(LocalDateTime.now());
            order.setPayStatus(Orders.PAID);
            order.setStatus(Orders.TO_BE_CONFIRMED);
            orderMapper.update(order);
            Map param = new HashMap<>();
            param.put("type",1);
            param.put("orderId",order.getId());
            param.put("content","订单号："+orderNumber);
            String json = JSON.toJSONString(param);
            webSocketServer.sendToAllClient(json);
        }
    }

    @Override
    public PageResult pageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<Orders> page = orderMapper.listByPage(ordersPageQueryDTO);
        //得到订单详情集合前提是得到已经返回的订单集合的ID
        for (Orders orders : page){
            Long id = orders.getId();
            List<OrderDetail> orderDetailList = orderMapper.listDetailsByOrderId(id);
            String orderDishes = "";
            for (OrderDetail orderDetail : orderDetailList){
                orderDishes += orderDetail.getName() + "*" + orderDetail.getNumber() + "，";
            }
            orders.setOrderDishes(orderDishes);
        }
        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public OrderWithDetailVO getOrderWithDetailById(Long id) {
        Orders order = orderMapper.getById(id);
        List<OrderDetail> orderDetailList = orderMapper.listDetailsByOrderId(id);
        OrderWithDetailVO orderWithDetailVO = new OrderWithDetailVO();
        BeanUtils.copyProperties(order, orderWithDetailVO);
        orderWithDetailVO.setOrderDetailList(orderDetailList);
        return orderWithDetailVO;
    }

    @Override
    public OrderStatisticsVO statistics() {
        return orderMapper.statistics();
    }

    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersConfirmDTO, orders);
        orders.setStatus(Orders.CONFIRMED);
        orderMapper.changeStatus(orders);
    }

    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersRejectionDTO, orders);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        orders.setCancelReason(ordersRejectionDTO.getRejectionReason());
        orderMapper.rejection(orders);
    }

    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersCancelDTO, orders);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.rejection(orders);
    }

    @Override
    public void delivery(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.changeStatus(orders);
    }

    @Override
    public void complete(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        orderMapper.changeStatus(orders);
    }

    @Override
    public PageResult userPageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        Page<Orders> page = orderMapper.userPageQuery(ordersPageQueryDTO);
        Page<OrderWithDetailVO> page1 = new Page<>();
        for (Orders orders : page){
            OrderWithDetailVO orderWithDetailVO = new OrderWithDetailVO();
            Long id = orders.getId();
            List<OrderDetail> orderDetailList = orderMapper.listDetailsByOrderId(id);
            BeanUtils.copyProperties(orders, orderWithDetailVO);
            orderWithDetailVO.setOrderDetailList(orderDetailList);
            page1.add(orderWithDetailVO);
        }
        return new PageResult(page.getTotal(), page1.getResult());
    }

    @Override
    public void repetition(Long id) {
        //接到再来一单后，跳转到购物页面并且已经把该订单包含的内容添加到购物车里面
        List<OrderDetail> orderDetailList = orderMapper.listDetailsByOrderId(id);
        List<ShoppingCart> shoppingCartList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList){
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setUserId(BaseContext.getCurrentId());
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCartList.add(shoppingCart);
        }
        shoppingCartMapper.insertBatch(shoppingCartList);
    }

    @Override
    public List<Orders> getOrdersTimeOut(Integer status, LocalDateTime localDateTime) {
        return orderMapper.listByTimeOut(status, localDateTime);
    }

    @Override
    public void reminder(Long id) {
        Orders orders = orderMapper.getById(id);
        if (orders == null){
            throw new DeletionNotAllowedException(MessageConstant.ORDER_NOT_FOUND);
        }
        Map param = new HashMap<>();
        param.put("type",2);
        param.put("orderId",id);
        param.put("content","提醒：订单号："+orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(param));
    }
}
